package gui;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.Timer;
import java.net.URL;

import app.AppInterface;

public class GuiTray {

	private final boolean DEBUG = false;

	private JFrame frame;
	private AppInterface app;
	private TrayIcon trayIcon;
	private Image image, image2;
	private MenuItem syncItem, cancelItem;
	private Timer timer = null;
	private int filesExpected, fileProgress;

	public GuiTray(JFrame frame, AppInterface app, GuiSync syncTab) {

		this.frame = frame;
		this.app = app;

		// Adds the system tray		
		if(SystemTray.isSupported()) {

			frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
			frame.setResizable(false);
			frame.addWindowListener(windowListener);


			SystemTray tray = SystemTray.getSystemTray();
			URL imgURL = ClassLoader.getSystemResource("skin/SyncITIcon.gif");
			image = Toolkit.getDefaultToolkit().getImage(imgURL);
			URL imgURL2 = ClassLoader.getSystemResource("skin/SyncITIcon2.gif");
			image2 = Toolkit.getDefaultToolkit().getImage(imgURL2);


			PopupMenu popup = new PopupMenu();
			MenuItem hideShowItem = new MenuItem("Hide/Show");
			hideShowItem.addActionListener(hideShowListener);
			MenuItem exitItem = new MenuItem("Exit");
			exitItem.addActionListener(exitListener);
			syncItem = new MenuItem("Sync");
			syncItem.addActionListener(syncTab.syncListener);
			cancelItem = new MenuItem("Cancel");
			cancelItem.addActionListener(syncTab.cancelListener);
			popup.add(hideShowItem);
			popup.addSeparator();
			popup.add(syncItem);
			popup.add(cancelItem);
			popup.addSeparator();
			popup.add(exitItem);

			// Sets the text message displayed when the mouse is over the tray icon
			String trayLine = app.getLastSyncDoneMsg();
			if(trayLine.split(";")[0].equals(" ")) {
				trayLine = "Sync IT";
			}
			else {
				trayLine = "Sync IT \n" + trayLine.split(";")[0] + " \n" + trayLine.split(";")[1];
			}

			trayIcon = new TrayIcon(image, trayLine, popup);
			trayIcon.setImageAutoSize(true);
			try {
				tray.add(trayIcon);
			} catch (AWTException e) {
				if(DEBUG) System.err.println("TrayIcon could not be added.");
			}
			trayIcon.addActionListener(hideShowListener);

			timer = new Timer(850, changeIconListener);
		}
		// If the the system does not support system tray, do this instead
		else {
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		}
	}


	public void setGuiTray() {

		if(DEBUG) System.out.println("Init gui tray");

		if(!app.getStartListen() && !app.getLocalSync()) {
			syncItem.setEnabled(false);
			cancelItem.setEnabled(false);
		}
	}


	public void showSyncItem(boolean show) {
		syncItem.setEnabled(show);
	}

	public void showCancelItem(boolean show) {
		cancelItem.setEnabled(show);
	}


	// Adds Listeners

	private ActionListener hideShowListener = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			frame.setVisible(!frame.isVisible());
		}
	};

	private ActionListener exitListener = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			app.setVisibleGui(frame.isVisible());
			app.saveConfig();
			System.exit(0);
		}
	};

	private WindowAdapter windowListener = new WindowAdapter() {
		public void windowClosing(WindowEvent we){
			if(app.getFirstStart()) {
				trayIcon.displayMessage("Sync IT", "The program is running in the background!", TrayIcon.MessageType.INFO);
			}
		}
	};

	private ActionListener changeIconListener = new ActionListener() {
		public void actionPerformed(ActionEvent event) {
			if(trayIcon.getImage().equals(image)) {
				trayIcon.setImage(image2);
			}
			else {
				trayIcon.setImage(image);
			}
		}
	};



	// Methods that comes from GuiChangeObserver, sent through the mainGui //

	public void enableGuiComponents(boolean show) {

		if(!show) { // disable component
			syncItem.setEnabled(false);
			trayIcon.setImage(image2); // Change the tray icon image
			timer.start();
		}
		else { // enable component
			if(app.getStartListen() || app.getLocalSync()) {
				syncItem.setEnabled(true);
			}
			timer.stop();
			trayIcon.setImage(image); // Restore the tray icon image
		}
	}


	// Methods that comes from LogToGuiObserver, sent through the mainGui //

	public void transferMessage(String message) {
		if(message.startsWith("Folders are synced") || message.startsWith("Sync session done")) {
			trayIcon.setToolTip("Sync IT\n" + message.split(";")[0] + "\n" + message.split(";")[1]);
			app.setLastSyncDoneMsg(message);
		}
		else if(message.startsWith("Gathering data")) {
			trayIcon.setToolTip("Sync IT\nSync in progress...");
		}
	}

	public void connectionStatusWarning(String message) {
		trayIcon.setToolTip("Sync IT\nSync failed\n" + message.split(";")[0] + "\n" + message.split(";")[1]);
	}


	// Methods that comes from GuiChangeObserver, sent through the mainGui //

	public void initFileTransfer(int noOfFiles, long totalOfBytes) {
		filesExpected = noOfFiles;
		fileProgress = 0;
		trayIcon.setToolTip("Sync IT\nSync in progress...\n" +
				fileProgress + " / " + filesExpected + " done");
	}

	public void fileInProgress() {
		fileProgress++;
		trayIcon.setToolTip("Sync IT\nSync in progress...\n" +
				fileProgress + " / " + filesExpected + " done");
	}
}
